package org.zfes.snowy.base.web;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationNonCheckedException;
import org.apache.shiro.authc.AuthenticationUnregisterException;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.session.InvalidSessionUserException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.zfes.snowy.base.web.controller.BaseController;
import org.zfes.snowy.core.consts.FrameConst;
import org.zfes.snowy.core.events.ErrorAppearEvent;
import org.zfes.snowy.core.exceptions.ServiceLogicalException;
import org.zfes.snowy.core.util.ZStrUtil;
import org.zfes.snowy.core.util.ZWebUtil;

@ControllerAdvice  
public class AppExceptionHandler extends BaseController{
	
	@Autowired  
	private  ApplicationEventPublisher publisher;
	
	@ExceptionHandler
	@ResponseBody
	public Object processGlobalExceptions(HttpServletRequest request,HttpServletResponse httpResponse, HandlerMethod handlerMethod, Exception e ) throws Exception {
		if (e instanceof ServiceLogicalException) {
			 if(ZWebUtil.isAjax(request)){
				 ZWebUtil.respJSON(httpResponse, ajaxDoneError(e.getMessage()));
				 return null;
			 }else{
				 httpResponse.setHeader(FrameConst.ZFES_HEADER_MSG, java.net.URLEncoder.encode(e.getMessage(), "UTF-8"));
				 ZWebUtil.redirect(request, httpResponse, FrameConst.ERROR_PAGE.ERROR_PAGE_300);
				 return null;
			 }
		}else if (e instanceof AuthenticationException) {//未认证
			if(ZWebUtil.isAjax(request)){
				  ZWebUtil.respJSON(httpResponse, ajaxAuthError(FrameConst.WEB_MSG.AUTH_ERROR+(ZStrUtil.trimToEmpty(""))));
				 return null;
			 }else{
				 ZWebUtil.redirect(request, httpResponse, FrameConst.ERROR_PAGE.ERROR_PAGE_401);
				 return null;
			 }
		}else if (e instanceof InvalidSessionUserException) {//获取session用户错误
			if(ZWebUtil.isAjax(request)){
				  ZWebUtil.respJSON(httpResponse, ajaxAuthError(FrameConst.SC.SC_301,FrameConst.WEB_MSG.INVALID_SESSIONUSER+(ZStrUtil.trimToEmpty(""))));
				 return null;
			 }else{
				 ZWebUtil.redirect(request, httpResponse, FrameConst.ERROR_PAGE.ERROR_PAGE_301);
				 return null;
			 }
		} else if (e instanceof UnauthorizedException) {//未授权
			StringBuffer msg=new StringBuffer().append("您没有");
			RequiresPermissions annrq=handlerMethod.getMethodAnnotation(RequiresPermissions.class);
			if(annrq!=null){
				msg.append("[").append(annrq.desc()).append("]");
			}
			msg.append("权限");
			if(ZWebUtil.isAjax(request)){
				  ZWebUtil.respJSON(httpResponse, ajaxAuthError(FrameConst.WEB_MSG.AUTH_ERROR+msg));
				 return null;
			 }else{
				 ZWebUtil.redirect(request, httpResponse, FrameConst.ERROR_PAGE.ERROR_PAGE_401);
				 return null;
			 }
		} else if (e instanceof AuthenticationUnregisterException) {//已经登录，但是游客模式---未注册-4010
			if(ZWebUtil.isAjax(request)){
				  ZWebUtil.respJSON(httpResponse, ajaxAuthError(FrameConst.SC.SC_4010,FrameConst.WEB_MSG.AUTH_UNREGISTER_ERROR+(ZStrUtil.trimToEmpty(""))));
				 return null;
			 }else{
				 ZWebUtil.redirect(request, httpResponse, FrameConst.ERROR_PAGE.ERROR_PAGE_401);
				 return null;
			 }
		}  else if (e instanceof AuthenticationNonCheckedException) {//已经注册，但是未审核
			if(ZWebUtil.isAjax(request)){
				  ZWebUtil.respJSON(httpResponse, ajaxAuthError(FrameConst.SC.SC_4011,FrameConst.WEB_MSG.AUTH_NONCHECKED_ERROR+(ZStrUtil.trimToEmpty(""))));
				 return null;
			 }else{
				 ZWebUtil.redirect(request, httpResponse, FrameConst.ERROR_PAGE.ERROR_PAGE_401);
				 return null;
			 }
		}else if(e instanceof Exception){
			e.printStackTrace();
			publisher.publishEvent(new ErrorAppearEvent(request,e.getMessage(),e));
			 if(ZWebUtil.isAjax(request)){
				 //与银行、SAM第三方对接异常，已做操作已完成，无须重复
				 ZWebUtil.respJSON(httpResponse, ajaxRunTimeError(FrameConst.WEB_MSG.RUNTOME_ERROR+"||"+e.getMessage() ));
				 //ZWebUtil.respJSON(httpResponse, ajaxDoneError("与银行或SAM第三方对接异常，已做操作已完成，无须重复"));
				  return null;
			 }else{
				  ZWebUtil.redirect(request, httpResponse, FrameConst.ERROR_PAGE.ERROR_PAGE_500);
				  return null;
			 }
		}
		return null;
	}

	public ApplicationEventPublisher getPublisher() {
		return publisher;
	}

	public void setPublisher(ApplicationEventPublisher publisher) {
		this.publisher = publisher;
	} 
}
